#include <iostream>
#include <sys/cdefs.h>
#include <type_traits>
using namespace std;

#define Print(x)                                                               \
    { cout << #x << "\t" << x<T>::value << endl; }

template <typename T> void type_traits_output(const T& x) {
    cout << "============================================type traits for type "
            "start:"
         << typeid(x).name() << endl;
    Print(is_void);
    Print(is_integral);
    Print(is_floating_point);
    Print(is_arithmetic);
    Print(is_signed);
    Print(is_unsigned);
    Print(is_const);
    Print(is_volatile);
    Print(is_class);
    Print(is_function);
    Print(is_reference);
    Print(is_lvalue_reference);
    Print(is_rvalue_reference);
    Print(is_pointer);
    Print(is_member_pointer);
    Print(is_member_object_pointer);
    Print(is_member_function_pointer);
    Print(is_fundamental);
    Print(is_scalar);
    Print(is_object);
    Print(is_compound);
    Print(is_standard_layout);
    Print(is_pod);
    Print(is_literal_type);
    Print(is_empty);
    Print(is_polymorphic);
    Print(is_abstract);
    Print(has_virtual_destructor);
    Print(is_default_constructible);
    Print(is_copy_constructible);
    Print(is_move_constructible);
    Print(is_copy_assignable);
    Print(is_move_assignable);
    Print(is_destructible);
    Print(is_trivial);
    cout << "============================================type traits for type "
            "end:"
         << typeid(x).name() << endl;
}
class Foo {
  private:
    int d1, d2;
};
class Goo {
  public:
    virtual ~Goo();

  private:
    int d1, d2;
};
namespace YTQ {
    ///////////////////////////////////////
template <typename Tp> struct remove_const { typedef Tp type; };
template <typename Tp> struct remove_const<Tp const > { typedef Tp type; };

template <typename Tp> struct remove_volatile { typedef Tp type; };
template <typename Tp> struct remove_volatile<Tp volatile> { typedef Tp type; };
template <typename Tp> struct remove_cv {
    typedef
        typename remove_const<typename remove_volatile<Tp>::type>::type type;
};
///////////////////////////
template<typename Tp>
struct add_const{
    typedef Tp const type;
};
template<typename Tp>
struct add_volatile{
    typedef Tp volatile type;
};
template<typename Tp>
struct add_cv{
    typedef typename add_const<typename add_volatile<Tp>::type>::type type;
};

} // namespace YTQ
void testTypeTraits() {

    type_traits_output(string());
    type_traits_output(Foo());
}